package dobest.ray.com.jiongjiong.views;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.LinearLayout;

import dobest.ray.com.jiongjiong.R;


public class ColorfulRingProgressView extends LinearLayout {

    private float mPercent = 0;
    private float showPercent = 0;
    private float mStrokeWidth;
    private int mBgColor = 0x00b9a9;
    private float mStartAngle = 0;
    private int mFgColorStart = 0xffffe400;
    private int mFgColorEnd = 0xffff4800;

    private LinearGradient mShader;
    private Context mContext;
    private RectF mOval;
    private RectF mOvalBig;
    private Paint mPaint;

    private int offsetOval = 10;
    private ProgressTextCallback callback;


    public ColorfulRingProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;

        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.ColorfulRingProgressView,
                0, 0);

        try {
            mBgColor = a.getColor(R.styleable.ColorfulRingProgressView_bgColor, mBgColor);
            mFgColorEnd = a.getColor(R.styleable.ColorfulRingProgressView_fgColorEnd, mFgColorEnd);

            mFgColorStart = a.getColor(R.styleable.ColorfulRingProgressView_fgColorStart, mFgColorStart);
            mPercent = a.getFloat(R.styleable.ColorfulRingProgressView_percent, 75);
            mStartAngle = a.getFloat(R.styleable.ColorfulRingProgressView_startAngle, 0) + 270;
            mStrokeWidth = a.getDimensionPixelSize(R.styleable.ColorfulRingProgressView_strokeWidth, dp2px(21));
            System.out.println("**** m" + mStrokeWidth);
        } finally {
            a.recycle();
        }

        init();
    }

    private void init() {
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mStrokeWidth);
        mPaint.setStrokeCap(Paint.Cap.BUTT);
    }

    private int dp2px(float dp) {
        return (int) (mContext.getResources().getDisplayMetrics().density * dp + 0.5f);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        mPaint.setShader(null);
        mPaint.setColor(mBgColor);

        BlurMaskFilter maskFilter = new BlurMaskFilter(10, BlurMaskFilter.Blur.SOLID);
        mPaint.setMaskFilter(maskFilter);
        canvas.drawArc(mOval, 0, 360, false, mPaint);

        mPaint.setShader(mShader);
        canvas.drawArc(mOvalBig, mStartAngle, showPercent * 3.6f, false, mPaint);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        updateOval();

        mShader = new LinearGradient(mOvalBig.left, mOvalBig.top,
                mOvalBig.left, mOvalBig.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR);
    }

    public float getPercent() {
        return mPercent;
    }

    public void setPercent(float mPercent) {
        this.mPercent = mPercent;
        new CountThread();
        refreshTheLayout();
    }

    public float getStrokeWidth() {
        return mStrokeWidth;
    }

    public void setStrokeWidth(float mStrokeWidth) {
        this.mStrokeWidth = mStrokeWidth;
        mPaint.setStrokeWidth(mStrokeWidth);
        updateOval();
        refreshTheLayout();
    }

    private void updateOval() {
        int xp = getPaddingLeft() + getPaddingRight();
        int yp = getPaddingBottom() + getPaddingTop();
        mOval = new RectF(getPaddingLeft() + mStrokeWidth, getPaddingTop() + mStrokeWidth,
                getPaddingLeft() + (getWidth() - xp) - mStrokeWidth,
                getPaddingTop() + (getHeight() - yp) - mStrokeWidth);
        mOvalBig = new RectF(getPaddingLeft() + mStrokeWidth - offsetOval, getPaddingTop() + mStrokeWidth - offsetOval,
                getPaddingLeft() + (getWidth() - xp) - mStrokeWidth + offsetOval,
                getPaddingTop() + (getHeight() - yp) - mStrokeWidth + offsetOval);
    }

    public void setStrokeWidthDp(float dp) {
        this.mStrokeWidth = dp2px(dp);
        mPaint.setStrokeWidth(mStrokeWidth);
        updateOval();
        refreshTheLayout();
    }

    public void refreshTheLayout() {
        invalidate();
        requestLayout();
    }

    public int getFgColorStart() {
        return mFgColorStart;
    }

    public void setFgColorStart(int mFgColorStart) {
        this.mFgColorStart = mFgColorStart;
        mShader = new LinearGradient(mOval.left, mOval.top,
                mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR);
        refreshTheLayout();
    }

    public int getFgColorEnd() {
        return mFgColorEnd;
    }

    public void setFgColorEnd(int mFgColorEnd) {
        this.mFgColorEnd = mFgColorEnd;
        mShader = new LinearGradient(mOval.left, mOval.top,
                mOval.left, mOval.bottom, mFgColorStart, mFgColorEnd, Shader.TileMode.MIRROR);
        refreshTheLayout();
    }


    public float getStartAngle() {
        return mStartAngle;
    }

    public void setStartAngle(float mStartAngle) {
        this.mStartAngle = mStartAngle + 270;
        refreshTheLayout();
    }

    class CountThread implements Runnable {
        private Thread thread;
        private int statek;
        int count;

        public CountThread() {
            thread = new Thread(this);
            thread.start();
        }

        public void run() {
            while (true) {
                switch (statek) {
                    case 0:
                        try {
                            Thread.sleep(200);
                            statek = 1;
                        } catch (InterruptedException e) {
                        }
                        break;
                    case 1:
                        try {
                            Thread.sleep(30);
                            if (showPercent < mPercent) {
                                showPercent += 1;
                                if (callback != null) {
                                    callback.callbackProgress(showPercent < mPercent ? (int) showPercent : (int) mPercent);
                                }
                            } else {
                                break;
                            }
                            count++;
                            postInvalidate();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        break;
                }
                if (count >= mPercent || showPercent >= mPercent)
                    break;
            }
        }
    }

    public void setProgressCallback(ProgressTextCallback callback) {
        this.callback = callback;
    }

    public interface ProgressTextCallback {
        void callbackProgress(int pregress);
    }

}
